home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Utilities Professional 1-1500
/
Utilities Professional 1-1500 (1994)(WPD)[!].iso
/
10011250
/
var1153.dms
/
var1153.adf
/
GoldED2
/
Tools
/
EDSource
/
main.c
next >
Wrap
C/C++ Source or Header
|
1992-09-02
|
10KB
|
425 lines
/* -----------------------------------------------------------------------------
ED v0.91 - GoldED quick starter, ©1993 Dietmar Eilert. DICE:
dcc main.c -// -proto -mRR -mi -r -2.0 -o ram:ED
------------------------------------------------------------------------------
*/
/// "includes"
#include <amiga20/exec/exec.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <amiga20/intuition/intuition.h>
#include <amiga20/dos/dos.h>
#include <amiga20/dos/dosextens.h>
#include <amiga20/dos/rdargs.h>
#include <amiga20/dos/dostags.h>
#include <amiga20/workbench/startup.h>
#include <amiga20/workbench/workbench.h>
#include <amiga20/rexx/errors.h>
#include <amiga20/rexx/rxslib.h>
#include <amiga20/clib/alib_protos.h>
#include <amiga20/clib/dos_protos.h>
#include <amiga20/clib/exec_protos.h>
#include <amiga20/clib/icon_protos.h>
#include <amiga20/clib/intuition_protos.h>
#include <amiga20/clib/utility_protos.h>
#include <amiga20/clib/rexxsyslib_protos.h>
#include <amiga20/clib/wb_protos.h>
#ifdef PRAGMAS
#include "Pragmas/exec.h"
#include "Pragmas/disk.h"
#include "Pragmas/diskfont.h"
#include "Pragmas/dynamic.h"
#include "Pragmas/gadtools.h"
#include "Pragmas/keymap.h"
#include "Pragmas/graphics.h"
#include "Pragmas/icon.h"
#include "Pragmas/input.h"
#include "Pragmas/intuition.h"
#include "Pragmas/layers.h"
#include "Pragmas/locale.h"
#include "Pragmas/misc.h"
#include "Pragmas/timer.h"
#include "Pragmas/wb.h"
#include "Pragmas/xpkmaster.h"
#include "Pragmas/amigaguide.h"
#include "Pragmas/reqtools.h"
#endif
#define Prototype extern
#define MAX_LEN 120
#define ARGBUFFER_SIZE 10500
#define ARGBUFFER_LIMIT 10000
///
/// "prototypes"
Prototype void main(ULONG, char **);
Prototype int wbmain(struct WBStartup *);
Prototype void Action(char *, char *, char *, BOOL, BOOL);
Prototype char *StartGED(char *, char *, BOOL);
Prototype struct RexxMsg *SendRexxCommand(char *, char *, struct MsgPort *);
Prototype void FreeRexxCommand (struct RexxMsg *);
Prototype ULONG WaitForAnswer(struct MsgPort *);
Prototype char *QuotedString(char *);
extern struct Library *IconBase;
extern struct Library *DOSBase;
extern struct Library *SysBase;
extern struct Library *IntuitionBase;
///
/// "entry points"
/* --------------------------------------- main --------------------------------
CLI entry point. Parse command line - create a string <argBuffer> containing
provided file names (file names are made absolute). This string has to be
FreeVec()'ed later on. Additionally, command line options are checked. They
won't have any effect if we manage to pass our list of files to a GoldED
process since we than have to accept that editor's configuration. However,
these options will be considered if we launch a new GoldED process.
*/
void
main(argc, argv)
ULONG argc;
char *argv[];
{
char *argBuffer;
if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
struct RDArgs *rdArgs;
ULONG args[] = { 0, 0, 0, 0, 0 };
if (rdArgs = ReadArgs("C=CONFIG/K,S=SCREEN/K,Y=STICKY/S,F=FILE/M,HIDE/S", args, NULL)) {
if (args[3]) {
char **nextFile, path[MAX_LEN + 1];
for (nextFile = (char **)args[3]; *nextFile; ++nextFile) {
BPTR lock;
strcpy(path, *nextFile);
if (lock = Lock(path, ACCESS_READ)) {
NameFromLock(lock, path, MAX_LEN);
UnLock(lock);
}
strcat(argBuffer, QuotedString(path));
if (strlen(argBuffer) > ARGBUFFER_LIMIT)
break;
}
}
Action(argBuffer, (char *)args[0], (char *)args[1], (BOOL)args[2], (BOOL)args[4]);
FreeArgs(rdArgs);
}
else
exit(20);
}
exit(0);
}
/* ------------------------------------ wbmain ---------------------------------
Workbench entry point. Read tooltypes of ED icon to decide wether user
prefers a special configuration/public screen. Tooltypes are only
considered if we don't find a running GoldED task, i.e. if we don't have to
acccept a running environment.
*/
int
wbmain(struct WBStartup *wbs)
{
char *argBuffer;
if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
struct DiskObject *diskObject;
char *config, *screen, progName[MAX_LEN + 1];
BOOL hide;
screen = NULL;
config = NULL;
hide = FALSE;
NameFromLock(GetProgramDir(), progName, MAX_LEN);
AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
if (diskObject = GetDiskObject(progName)) {
config = FindToolType(diskObject->do_ToolTypes, "CONFIG");
screen = FindToolType(diskObject->do_ToolTypes, "SCREEN");
if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
hide = TRUE;
}
if (--wbs->sm_NumArgs) {
char file[MAX_LEN + 1];
struct WBArg *wbArg = wbs->sm_ArgList;
while ((wbs->sm_NumArgs)--) {
++wbArg;
NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
AddPart(file, wbArg->wa_Name, MAX_LEN);
strcat(argBuffer, QuotedString(file));
if (strlen(argBuffer) > ARGBUFFER_LIMIT)
break;
}
}
Action(argBuffer, config, screen, FALSE, hide);
if (diskObject)
FreeDiskObject(diskObject);
}
exit(0);
}
///
/// "main routine"
/* ------------------------------------ Action ---------------------------------
Send LOCK ARexx messages to running GoldED. Wait for positive reply, pass
our list of <files> to that editor, unlock editor (use delayed unlock
unless <sticky> is specified). Suggestions for improvements: Make the whole
thing aynchrounous. Send LOCK messages to all running instances of GoldED,
then wait for first reply (or timeout).
*/
void
Action(files, config, screen, sticky, hide)
char *files, *config, *screen;
BOOL sticky, hide;
{
BOOL success = FALSE;
char *host;
if (host = StartGED(config, screen, hide)) {
if (*files || !hide) {
struct MsgPort *replyPort;
if (replyPort = CreateMsgPort()) {
if (SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
if (success = (WaitForAnswer(replyPort) == RC_OK)) {
if (*files)
strins(files, "OPEN SMART QUIET ");
else
strcpy(files, "MORE SMART");
if (SendRexxCommand(host, files, replyPort))
WaitForAnswer(replyPort);
if (SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK DELAY", replyPort))
WaitForAnswer(replyPort);
}
}
DeleteMsgPort(replyPort);
}
}
}
FreeVec(files);
}
///
/// "misc"
/* ------------------------------------- StartGED -----------------------------
Look for running instance of GoldED. Launch a new task if none is found.
Return pointer to host name (or NULL). Screen/config keywords are only
considered if a new GoldED process has to be launched, i.e. if we aren't
bound to an existing environment.
*/
char *
StartGED(config, screen, hide)
char *config, *screen;
BOOL hide;
{
static char host[] = "GOLDED.1";
char command[MAX_LEN + 1];
UWORD try;
for (try = '9'; try >= '1'; try--) {
host[7] = try;
if (FindPort(host))
return(host);
}
strcpy(command, "GoldED:GoldED ");
if (hide)
strcat(command, "HIDE ");
if (config) {
strcat(command, "CONFIG ");
strcat(command, QuotedString(config));
}
if (screen) {
strcat(command, "SCREEN ");
strcat(command, QuotedString(screen));
}
if (!SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, TAG_DONE))
for (try = 50; try; try--, Delay(10))
if (FindPort(host))
return(host);
return(FALSE);
}
/* ------------------------------------ QuotedString --------------------------
Add quotation marks to string (to avoid import of sprintf)
*/
char *
QuotedString(char *text)
{
static char buffer[MAX_LEN + 1];
strcpy(buffer, "\42");
strcat(buffer, text );
strcat(buffer, "\42");
return(buffer);
}
///
/// "ARexx"
/* -------------------------------------- WaitForAnswer -----------------------
Wait for answer on previously sent message. Free message afterwards.
Primary return code is returned.
*/
ULONG
WaitForAnswer(port)
struct MsgPort *port;
{
struct RexxMsg *rexxMsg;
ULONG result;
do {
WaitPort(port);
if (rexxMsg = (struct RexxMsg *)GetMsg(port))
result = rexxMsg->rm_Result1;
} while (!rexxMsg);
FreeRexxCommand(rexxMsg);
return(result);
}
/* ------------------------------------- FreeRexxCommand ----------------------
Free ARexx message
*/
void
FreeRexxCommand(rexxmessage)
struct RexxMsg *rexxmessage;
{
if (rexxmessage->rm_Result1 == RC_OK)
if (rexxmessage->rm_Result2)
DeleteArgstring((char *)rexxmessage->rm_Result2);
DeleteArgstring((char *)ARG0(rexxmessage));
DeleteRexxMsg(rexxmessage);
}
/* ---------------------------------- SendRexxCommand -------------------------
Send ARexx message
*/
struct RexxMsg *
SendRexxCommand(port, cmd, replyPort)
char *cmd, *port;
struct MsgPort *replyPort;
{
struct MsgPort *rexxport;
struct RexxMsg *rexx_command_message = NULL;
Forbid();
if (rexxport = FindPort(port)) {
if (rexx_command_message = CreateRexxMsg(replyPort, NULL, NULL)) {
if (rexx_command_message->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
PutMsg(rexxport, &rexx_command_message->rm_Node);
}
}
}
Permit();
return(rexx_command_message);
}
///